using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using CKY.AgentPlatform.Caching;

namespace CKY.AgentPlatform.Application.Caching
{
    /// <summary>
    /// 分布式缓存服务实现
    /// </summary>
    public class CachingService : ICachingService
    {
        private readonly IDistributedCache _cache;
        private readonly ILogger<CachingService> _logger;

        public CachingService(IDistributedCache cache, ILogger<CachingService> logger)
        {
            _cache = cache;
            _logger = logger;
        }

        /// <summary>
        /// 获取缓存值
        /// </summary>
        public async Task<string> GetAsync(string key)
        {
            try
            {
                var value = await _cache.GetStringAsync(key);
                _logger.LogDebug("获取缓存值: {Key}, 结果: {HasValue}", key, !string.IsNullOrEmpty(value));
                return value;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取缓存值失败: {Key}", key);
                return null;
            }
        }

        /// <summary>
        /// 设置缓存值
        /// </summary>
        public async Task SetAsync(string key, string value, int? expirationSeconds = null)
        {
            try
            {
                var options = new DistributedCacheEntryOptions();

                if (expirationSeconds.HasValue)
                {
                    options.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(expirationSeconds.Value);
                }
                else
                {
                    // 默认过期时间：1小时
                    options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);
                }

                await _cache.SetStringAsync(key, value, options);
                _logger.LogDebug("设置缓存值: {Key}, 过期时间: {Expiration}", key, expirationSeconds ?? 3600);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设置缓存值失败: {Key}", key);
                throw;
            }
        }

        /// <summary>
        /// 删除缓存值
        /// </summary>
        public async Task RemoveAsync(string key)
        {
            try
            {
                await _cache.RemoveAsync(key);
                _logger.LogDebug("删除缓存值: {Key}", key);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除缓存值失败: {Key}", key);
                throw;
            }
        }

        /// <summary>
        /// 检查缓存是否存在
        /// </summary>
        public async Task<bool> ExistsAsync(string key)
        {
            try
            {
                var value = await _cache.GetStringAsync(key);
                var exists = !string.IsNullOrEmpty(value);
                _logger.LogDebug("检查缓存存在: {Key}, 结果: {Exists}", key, exists);
                return exists;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查缓存存在失败: {Key}", key);
                return false;
            }
        }

        /// <summary>
        /// 清除所有缓存
        /// </summary>
        public async Task ClearAllAsync()
        {
            try
            {
                // 注意：IDistributedCache 没有直接的清除所有缓存的方法
                // 这里我们可以记录日志，但实际清除可能需要特定缓存实现的支持
                _logger.LogWarning("清除所有缓存请求 - IDistributedCache 不支持直接清除所有缓存");

                // 对于Redis等支持特定命令的缓存，可以在这里实现
                // 例如：如果使用Redis，可以执行 FLUSHDB 命令
                // 但为了保持通用性，这里只记录日志
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清除所有缓存失败");
                throw;
            }
        }

        /// <summary>
        /// 获取缓存值（泛型方法）
        /// </summary>
        public async Task<T> GetAsync<T>(string key) where T : class
        {
            try
            {
                var value = await GetAsync(key);
                if (string.IsNullOrEmpty(value))
                {
                    return null;
                }

                return JsonConvert.DeserializeObject<T>(value);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取缓存值失败（泛型）: {Key}, 类型: {Type}", key, typeof(T).Name);
                return null;
            }
        }

        /// <summary>
        /// 设置缓存值（泛型方法）
        /// </summary>
        public async Task SetAsync<T>(string key, T value, int? expirationSeconds = null) where T : class
        {
            try
            {
                var serializedValue = JsonConvert.SerializeObject(value);
                await SetAsync(key, serializedValue, expirationSeconds);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设置缓存值失败（泛型）: {Key}, 类型: {Type}", key, typeof(T).Name);
                throw;
            }
        }
    }
}